//
// Created by Andy on 2019/9/19.
//

#include <jni.h>
#include <android/log.h>
#include <memory>
#include <string>
#include "zinnia.h"
#include <string>

#ifdef __cplusplus
extern "C" {
#endif

jstring Utf8ToJString(JNIEnv *env, const char *utf) {
    return env->NewStringUTF(utf);
}

char *JStringToUtf8(JNIEnv *env, jstring str) {
    char *ret = NULL;
    jboolean isCopy = JNI_FALSE;
    const char *utf = env->GetStringUTFChars(str, &isCopy);
    jsize length =  env->GetStringUTFLength(str);
    length = length > 0 ? length : 1;
    ret = (char *)malloc(length + 1);
    if(utf) {
        strcpy(ret, utf);
    }
    ret[length] = 0;
    env->ReleaseStringUTFChars(str, utf);
    return ret;
}

void SafeFree(void **lp) {
    if(lp && (*lp)) {
        free((*lp));
        (*lp) = NULL;
    }
};

////////////////////////////////////////
JNIEXPORT jlong JNICALL Java_com_tomhw_zinnia_characterNew(JNIEnv* env, jclass cls) {
    jlong ret = jlong(zinnia_character_new());
    return ret;
}

JNIEXPORT void JNICALL Java_com_tomhw_zinnia_characterDestroy(JNIEnv* env, jclass cls, jlong character) {
    zinnia_character_destroy((zinnia_character_t *)character);
}

JNIEXPORT void JNICALL Java_com_tomhw_zinnia_characterClear(JNIEnv* env, jclass cls, jlong character) {
    zinnia_character_clear((zinnia_character_t *)character);
}

JNIEXPORT jint JNICALL Java_com_tomhw_zinnia_characterAdd(JNIEnv* env, jclass cls, jlong character, jlong id, jint x, jint y) {
    return jint(zinnia_character_add((zinnia_character_t *)character, size_t(id), int(x), int(y)));
}

JNIEXPORT void JNICALL Java_com_tomhw_zinnia_characterSetWidth(JNIEnv* env, jclass cls, jlong character, jlong width) {
    zinnia_character_set_width((zinnia_character_t *)character, size_t(width));
}

JNIEXPORT void JNICALL Java_com_tomhw_zinnia_characterSetHeight(JNIEnv* env, jclass cls, jlong character, jlong height) {
    zinnia_character_set_height((zinnia_character_t *)character, size_t(height));
}

JNIEXPORT jlong JNICALL Java_com_tomhw_zinnia_characterStrokesSize(JNIEnv* env, jclass cls, jlong character) {
    return jlong(zinnia_character_strokes_size((zinnia_character_t *)character));
}

////////////////////////////////////////
JNIEXPORT jlong JNICALL Java_com_tomhw_zinnia_recognizerNew(JNIEnv* env, jclass cls) {
    return jlong(zinnia_recognizer_new());
}

JNIEXPORT void JNICALL Java_com_tomhw_zinnia_recognizerDestroy(JNIEnv* env, jclass cls, jlong recognizer) {
    zinnia_recognizer_destroy((zinnia_recognizer_t *)recognizer);
}

JNIEXPORT jint JNICALL Java_com_tomhw_zinnia_recognizerOpen(JNIEnv* env, jclass cls, jlong recognizer, jstring filename) {
    jboolean isCopy = JNI_FALSE;
    const char* str = env->GetStringUTFChars(filename, &isCopy);
    int ret =  zinnia_recognizer_open((zinnia_recognizer_t *)recognizer, str);
    env->ReleaseStringUTFChars(filename, str);
    return  ret;
}

JNIEXPORT jstring JNICALL Java_com_tomhw_zinnia_recognizerStrerror(JNIEnv* env, jclass cls, jlong recognizer) {
    const char *str = zinnia_recognizer_strerror((zinnia_recognizer_t *)recognizer);
    return env->NewStringUTF(str ? str : "");
}

JNIEXPORT jlong JNICALL Java_com_tomhw_zinnia_recognizerClassify(JNIEnv* env, jclass cls, jlong recognizer, jlong character, jlong nbest) {
    return jlong(zinnia_recognizer_classify((zinnia_recognizer_t *)recognizer, (zinnia_character_t *)character, nbest));
}

////////////////////////////////////////
JNIEXPORT jstring JNICALL Java_com_tomhw_zinnia_resultValue(JNIEnv* env, jclass cls, jlong result, jlong i) {
    const char *str = zinnia_result_value((zinnia_result_t *)result, i);
    return env->NewStringUTF(str ? str : "");
}

JNIEXPORT jfloat JNICALL Java_com_tomhw_zinnia_resultScore(JNIEnv* env, jclass cls, jlong result, jlong i) {
    return zinnia_result_score((zinnia_result_t *)result, i);
}

JNIEXPORT jlong JNICALL Java_com_tomhw_zinnia_resultSize(JNIEnv* env, jclass cls, jlong result) {
    return zinnia_result_size((zinnia_result_t *)result);
}

JNIEXPORT void JNICALL Java_com_tomhw_zinnia_resultDestroy(JNIEnv* env, jclass cls, jlong result) {
    return zinnia_result_destroy((zinnia_result_t *)result);
}

#ifdef __cplusplus
}
#endif